/*
 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <hi_time.h>
#include <hi_mux.h>
#include <hi_uart.h>
#include "iot_uart.h"

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_i2c.h"
#include "iot_gpio.h"
#include "iot_errno.h"
#include "hi_io.h"
#include "hi_gpio.h"
#include "hi_task.h"
#include "hi_i2c.h"

#include "oled_ssd1306.h"
#include "app_demo_uart.h"



#define AHT20_BAUDRATE (400 * 1000) //波特率设置
#define AHT20_I2C_IDX 0
#define GapValue 230//误差调整
#define WIFI_IOT_UART_IDX_1 1
#define UART_BUFF_SIZE 1000

int class_num = 100;
int hx711_weight_int = 0;




static void OledmentTask(const char *arg)
{
    (void)arg;
    OledInit();
    OledFillScreen(0);
    IoTI2cInit(AHT20_I2C_IDX, AHT20_BAUDRATE);

    OledShowString(20, 3, "Hello  World", 1); /* 屏幕第20列3行显示1行 */
    OledShowString(20, 8, "UESTC", 1); /* 屏幕第20列3行显示1行 */
}

unsigned long Sensor_Read(void)
{
    unsigned long value = 0;
    unsigned char i = 1;
    hi_gpio_value input = 0;
    hi_udelay(2);
    //时钟线拉低 空闲时时钟线保持低电位
    hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,0);
    hi_udelay(2);
    hi_gpio_get_input_val(HI_IO_NAME_GPIO_11,&input);
    //等待AD转换结束
    while(input)
    {
        hi_gpio_get_input_val(HI_IO_NAME_GPIO_11,&input);
    }

    for(i=0;i<24;i++)
    {
        //时钟线拉高 开始发送时钟脉冲
        hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,1);
        hi_udelay(2);
        //左移位， 右侧补零 等待接收数据
        value = value << 1;
        //时钟线拉低
        hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,0);
        hi_udelay(2);
        //读取一位数据
        hi_gpio_get_input_val(HI_IO_NAME_GPIO_11,&input);
        if(input){
            value++;
        }
    }
    //第25个脉冲
    hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,1);
    hi_udelay(2);
    value = value^0x800000;
    hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,0);
    hi_udelay(2);

    return value;
    
}
double Get_Sensor_Read(void)
{
    double sum = 0; //为了减小误差，一次取出10个值后取平均值
    for (int i=0;i<5;i++){ //循环越多精度越高，耗费时间越高
        sum += Sensor_Read(); //累加
    }
    return (sum/5); //求均值
}

//hi_void hi_hjx711_task(hi_void)
static void hi_hjx711_task(const char *arg)
{ 
    (void)arg;
    //初始GPIO11为GPIO输入，为传感器DT引脚
    hi_io_set_func(HI_IO_NAME_GPIO_11,HI_IO_FUNC_GPIO_11_GPIO);
    hi_gpio_set_dir(HI_GPIO_IDX_11,HI_GPIO_DIR_IN);
    //初始GPIO12为GPIO输出，为传感器SCK引脚 
    hi_io_set_func(HI_IO_NAME_GPIO_12, HI_IO_FUNC_GPIO_12_GPIO);
    hi_gpio_set_dir(HI_GPIO_IDX_12,HI_GPIO_DIR_OUT);
    hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,0);
    //初始化I2C，OLED屏使用
    hi_i2c_init(HI_I2C_IDX_0, AHT20_BAUDRATE);
    hi_i2c_set_baudrate(HI_I2C_IDX_0, AHT20_BAUDRATE);
    //oled初始化并显示对应信息
    while(HI_ERR_SUCCESS != OledInit());
    OledFillScreen(0);
    OledShowString(0, 1, "Weight: ", 1); 
    OledShowString(0, 3, "Price: ", 1); /* 屏幕第20列3行显示1行 */
    OledShowString(0, 5, "Class: ", 1); /* 屏幕第20列3行显示1行 */

    double base_data = 0, hx711_weight = 0, hx711_weight_last=0;
    char* str=malloc(10);
    char* pri=malloc(10);
    
   // hi_u8 buf[10] = {0};
    float price0 = 11.98,price1 = 12.98,price2 = 39.80,price3 = 6.98,price4 = 14.80,price5 = 6.98,price6 = 9.99;
    float price7 = 32.98,price8 = 4.99,price9 = 19.80,price10 = 49.60,price11 = 13.90,price12 = 36.4,price13 = 14.60;
    float price14 = 18.60,price15 = 16,price16 = 3.99,price17 = 14.68,price18 = 19.98,price19 = 119.99;



    base_data = Get_Sensor_Read(); //获取基准值
    //printf("base_data:  %.2f\r\n",base_data);


    while (1)
    {
        /* code */
        hx711_weight = (Sensor_Read() - base_data) / GapValue; //获取重量
        //hx711_weight = Sensor_Read() - base_data ;
        //printf("Weight:  %.2f\r\n",hx711_weight);
        hx711_weight_last = hx711_weight;

        if(hx711_weight > 1) //大于0时显示
        {
            printf("Weight:  %.2f\r\n",hx711_weight);
            //sprintf_s(buf,10,"%.2f g", hx711_weight);
            hx711_weight_int = (int)hx711_weight;

            sprintf(str, "%d G", hx711_weight_int);
            // sprintf(pri, "%5.2f Y", hx711_weight * price);
            

           // OledShowChar(10, 3, hx711_weight, 1); 
            OledShowString(70, 1, str, 1); 
            //OledShowString(20, 5, '1111', 1); 

        if ((flag1== 0x0) && (flag2 == 0x0)){
            OledShowString(50, 5, "Passion_fruit", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price0 /1000);
            OledShowString(50, 3, pri, 1);
            class_num = 0; }
        else if ((flag1== 0x0) && (flag2 == 0x1)){
            OledShowString(50, 5, "Pineapple    ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price1 /1000);
            OledShowString(50, 3, pri, 1);
            class_num = 1;}
        else if ((flag1== 0x0) && (flag2 == 0x2)){
            OledShowString(50, 5, "Strawberry   ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price2/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 2;}
        else if ((flag1== 0x0) && (flag2 == 0x3)){
            OledShowString(50, 5, "Sugar_cane   ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price3/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 3;}
        else if ((flag1== 0x0) && (flag2 == 0x4)){
            OledShowString(50, 5, "Hami_melon   ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price4/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 4;}
        else if ((flag1== 0x0) && (flag2 == 0x5)){
            OledShowString(50, 5, "Pitaya       ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price5/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 5;}
        else if ((flag1== 0x0) && (flag2 == 0x6)){
            OledShowString(50, 5, "Orange       ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price6/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 6;}
        else if ((flag1== 0x0) && (flag2 == 0x7)){
            OledShowString(50, 5, "Blueberry    ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price7/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 7;}
        else if ((flag1== 0x0) && (flag2 == 0x8)){
            OledShowString(50, 5, "Pear         ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price8/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 8;}
        else if ((flag1== 0x0) && (flag2 == 0x9)){
            OledShowString(50, 5, "Litchi       ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price9/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 9;}
        else if ((flag1== 0x0) && (flag2 == 0xa)){
            OledShowString(50, 5, "Durian       ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price10/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 10;}
        else if ((flag1== 0x0) && (flag2 == 0xb)){
            OledShowString(50, 5, "Mango        ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price11/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 11;}
        else if ((flag1== 0x0) && (flag2 == 0xc)){
            OledShowString(50, 5, "Loquat       ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price12/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 12;} 
        else if ((flag1== 0x0) && (flag2 == 0xd)){
            OledShowString(50, 5, "Apple        ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price13/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 13;}
        else if ((flag1== 0x0) && (flag2 == 0xe)){
            OledShowString(50, 5, "Grape        ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price14/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 14;}
        else if ((flag1== 0x0) && (flag2 == 0xf)){
            OledShowString(50, 5, "Peach        ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price15/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 15;}
        else if ((flag1== 0x1) && (flag2 == 0x0)){
            OledShowString(50, 5, "Watermelon   ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price16/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 16;}
        else if ((flag1== 0x1) && (flag2 == 0x1)){
            OledShowString(50, 5, "Banana       ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price17/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 17;}
        else if ((flag1== 0x1) && (flag2 == 0x2)){
            OledShowString(50, 5, "Coconut      ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price18/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 18;}
        else if ((flag1== 0x1) && (flag2 == 0x3)){
            OledShowString(50, 5, "Cantaloupe   ", 1);
            sprintf(pri, "%5.2f Y", hx711_weight * price19/1000);
            OledShowString(50, 3, pri, 1);
            class_num = 19;}
        else if ((flag1== 0x1) && (flag2 == 0x4)){
            OledShowString(50, 5, "Mixed       ", 1);
            class_num = 20;}
        else{    
            OledShowString(50, 5, "Background   ", 1);
            class_num = 21;}
        }
        hi_sleep(3000);
        if (hx711_weight < 5){
        OledFillScreen(0);
        OledShowString(0, 1, "Weight:            ", 1); 
        OledShowString(0, 3, "Price:              ", 1); /* 屏幕第20列3行显示1行 */
        OledShowString(0, 5, "Class:              ", 1); /* 屏幕第20列3行显示1行 */

    }

}
}

static void OledDemo(void)
{
    osThreadAttr_t attr;
    attr.name = "hi_hjx711_task";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 8192; /* 任务大小，默认4096 */
    attr.priority = osPriorityNormal;

    if (osThreadNew(hi_hjx711_task, NULL, &attr) == NULL) {
        printf("[OledDemo] Falied to create hi_hjx711_task!\n");
    }
}

    // attr.name = "UART";
    // if (osThreadNew((osThreadFunc_t)UART, NULL, &attr) == NULL) {
    //     printf("Failed to create Thread2!\n");
    // }

APP_FEATURE_INIT(OledDemo);